/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ca.trader.regions;

import ca.trader.except.InvalidHttpRequestException;
import ca.trader.except.LocationNotFoundException;
import ca.trader.logger.TraderLogger;
import ca.trader.startup.ServletContextManager;
import ca.trader.utils.DebugUtils;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;

/**
 * Given the name of the a country and a region (via a GET or POST arguments), 
 * this servlet returns the cities in the region that are comma separated.
 * An example call to this servlet is "country=Canada&region=Ontario"
 * E.g., given country "Canada" and region "Ontario", this servlet will return value of 
 * "Barrie,Belleville,Brantford,Guelph,Hamilton,Kanata" and the other cities of Ontario.
 * If an invalid country or region is passed in the GET/POST argument, or GET/POST argument does not exist, then "null" is returned.
 * The return type is of plain text.
 * The GET/POST arguments' name must match the value of the PARAM_COUNTRY and PARAM_REGION variable.
 * @author Ahsan
 */
@WebServlet(name = "MapRegionToCities", urlPatterns =
{
	 "/MapRegionToCities"
})
public class MapRegionToCities extends HttpServlet
{
	 private static final String _className = MapRegionToCities.class.getName();

	 private static final String PARAM_COUNTRY = "country";
	 private static final String PARAM_REGION = "region";
	 
	 

	 /**
	  * Processes requests for both HTTP
	  * <code>GET</code> and
	  * <code>POST</code> methods.
	  *
	  * @param request servlet request
	  * @param response servlet response
	  * @throws ServletException if a servlet-specific error occurs
	  * @throws IOException if an I/O error occurs
	  */
	 protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	 {
		  String _methodName = "processRequest";

		  TraderLogger.logInfo(_className, _methodName, "Starting servlent: " + this.getServletName());

		  // set the response type as plain text
		  response.setContentType("text/plain;charset=UTF-8");
		  
		  // Get the reference to the writer
		  PrintWriter out = response.getWriter();

		  try
		  {

			   TraderLogger.logInfo(_className, _methodName, "Extracting Region Manager object from servlet context");
			   
			   // Get region manager (which contains the country/region/city data) from the servlet context manager
			   RegionManager regionManager = ServletContextManager.getRegionManager();

			   TraderLogger.logInfo(_className, _methodName, "Validating POST PARAMETERS");
			   
			   // If no argument for the country name or region name is passed in the GET/POST request, throw InvalidHttpRequestException
			   if (request.getParameter(PARAM_COUNTRY) == null || request.getParameter(PARAM_REGION) == null)
			   {
				    TraderLogger.logInfo(_className, _methodName, "Mandatory parameters not found: " + PARAM_COUNTRY + " or " + PARAM_REGION);

				    throw new InvalidHttpRequestException("Invalid Request");
			   }
			   
			   // Get the name of the country passed in the GET/POST request
			   String countryName = request.getParameter(PARAM_COUNTRY);

			   TraderLogger.logInfo(_className, _methodName, "Looking up regions for country: " + countryName);
			   
			   // Get the country object with the matching name
			   Country countryObject = regionManager.getCountry(countryName);

			   // If no country object found with that name, it means there is no country with that name.  
			   // Throw a LocationNotFoundException
			   if (countryObject == null)
			   {
				    TraderLogger.logInfo(_className, _methodName, "No country found with that name, returning null");
				    out.print("null");

				    throw new LocationNotFoundException("Country not found: " + countryName);

			   }			   

			   // Get the name of the region from GET/POST argument
			   String regionName = request.getParameter(PARAM_REGION);			   
			   
			   TraderLogger.logInfo(_className, _methodName, "Looking up city for region: " + regionName);
			   
			   // Get the region object with the matching name from the country object		   			   
			   Region regionObject = countryObject.getRegion(regionName);

			   // If no region object found with that name, it means there is no region with that name.  
			   // Throw a LocationNotFoundException
			   if (regionObject == null)
			   {
				    TraderLogger.logInfo(_className, _methodName, "No region found with that name, returning null");

				    throw new LocationNotFoundException("Region not found: " + regionName);

			   }
			   
			   // Get the list of the cities of the reigion, join them into one string comma separated.			   
			   String citiesCommaSeparated = StringUtils.join(regionObject.getCityList(), ",");
			   TraderLogger.logInfo(_className, _methodName, "Cities found: " + citiesCommaSeparated);
			   
			   // print that string that contains the list of cities comma separated			   
			   out.print(citiesCommaSeparated);


		  }
		  // Return null in case we have an exception
		  catch (InvalidHttpRequestException | LocationNotFoundException e)
		  {
			   TraderLogger.logInfo(_className, _methodName, e.getMessage());
			   out.print("null");

		  }
		  catch (Exception e)
		  {
			   TraderLogger.logSevere(_className, _methodName, "Unknown exception: " + e.getMessage(), DebugUtils.getStackTraceAsString(e));
			   out.print("null");

		  }
		  finally
		  {

			   TraderLogger.logInfo(_className, _methodName, "Exiting servlent: " + this.getServletName());
			   
			   // Close the output stream and the logger.
			   out.close();
		  }
	 }

	 // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
	 /**
	  * Handles the HTTP
	  * <code>GET</code> method.
	  *
	  * @param request servlet request
	  * @param response servlet response
	  * @throws ServletException if a servlet-specific error occurs
	  * @throws IOException if an I/O error occurs
	  */
	 @Override
	 protected void doGet(HttpServletRequest request, HttpServletResponse response)
		    throws ServletException, IOException
	 {
		  processRequest(request, response);
	 }

	 /**
	  * Handles the HTTP
	  * <code>POST</code> method.
	  *
	  * @param request servlet request
	  * @param response servlet response
	  * @throws ServletException if a servlet-specific error occurs
	  * @throws IOException if an I/O error occurs
	  */
	 @Override
	 protected void doPost(HttpServletRequest request, HttpServletResponse response)
		    throws ServletException, IOException
	 {
		  processRequest(request, response);
	 }

	 /**
	  * Returns a short description of the servlet.
	  *
	  * @return a String containing servlet description
	  */
	 @Override
	 public String getServletInfo()
	 {
		  return "Short description";
	 }// </editor-fold>

}
